#ifndef _CROSSENGINE_PRINTER_H_
#define _CROSSENGINE_PRINTER_H_
#include <stdio.h>
#include "template.h"
#include "thread.h"
#include "list.h"
#ifndef _WIN32
#include <fcntl.h>
#include <stdio.h>
#endif

namespace Cross
{
class Printer
{
public:
    virtual ~Printer(){}
    virtual void print(const char* s);
    virtual void warn(const char* s);
    virtual void error(const char* s);
    virtual void luaprint(const char* s);
};

template<bool MT>
class LogPrinter:public Printer
{
    typedef Printer base;
public:
    ~LogPrinter();
    LogPrinter();
    void OpenLog(const char* logFile);
    virtual void print(const char* s);
    virtual void warn(const char* s);
    virtual void error(const char* s);
    virtual void luaprint(const char* s);
private:
    typename if_<MT,UserMutex,NullMutex>::type _fileMutex;
    FILE* _file;
};

#ifndef _WIN32
class DupPrinter:public Printer
{
    typedef Printer base;
public:
    ~DupPrinter();
    DupPrinter();
    void OpenLog(const char* logFile);
private:
    int _file;
};
#endif

class ThreadPrinter:public Printer,public Thread
{
    typedef Printer base;
public:
    ~ThreadPrinter();
    explicit ThreadPrinter(Printer* printer,int queueSize);
    virtual void print(const char* s);
    virtual void warn(const char* s);
    virtual void error(const char* s);
    virtual void luaprint(const char* s);
protected:
    virtual void run();
private:
    enum LogType
    {
        LT_PRINT,
        LT_WARN,
        LT_ERROR,
        LT_LUAPRINT,
    };
    struct Log
    {
        list_head _lst;
        int _allocSize;
        LogType _type;
        char _str[1];
    };
    void Push(LogType type,const char* s);
    void DoThreadLoop();
    Printer* _printer;
    list_head _queue;
    UserMutex _queueMutex;
    int _maxQueueSize;
};

}
#endif//_CROSSENGINE_PRINTER_H_
